package com.itclass.oder;

import sun.misc.Unsafe;

import java.lang.reflect.Field;
import java.util.concurrent.*;
import java.util.concurrent.locks.LockSupport;

public class OrderCompletableFuture<T> {

    /**
     * 订单的任务状态  -1 取消 , 0 处理中 ，1：处理完成。
     */
    volatile int state;

    //等待线程
    volatile Thread waitThread;

    /**
     * 响应结果参数
     */
    volatile T result;
    private static final int CANCEL = -1;

    private static final int START = 0;
    private static final int COMPLETE = 1;


    public OrderCompletableFuture() {
        waitThread = Thread.currentThread();
        state = START;
    }

    private static final sun.misc.Unsafe UNSAFE;
    private static final long RESULT;
    private static final long STATE;

    static {
        try {
            final sun.misc.Unsafe u;
            UNSAFE = u = reflectGetUnsafe();
            Class<?> k = OrderCompletableFuture.class;
            RESULT = u.objectFieldOffset(k.getDeclaredField("result"));
            STATE = u.objectFieldOffset(k.getDeclaredField("state"));

        } catch (Exception x) {
            throw new Error(x);
        }
    }

    //引用Unsafe需使用如下反射方式，否则会抛出异常java.lang.SecurityException: Unsafe
    public static Unsafe reflectGetUnsafe() throws NoSuchFieldException, IllegalAccessException {
        Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
        theUnsafe.setAccessible(true);//禁止访问权限检查（访问私有属性时需要加上）
        return (Unsafe) theUnsafe.get(null);
    }

    public T get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
        T r;
        // 转换为纳秒
        long nanos = unit.toNanos(timeout);
        // 如果数据结果 null 并且不是取消状态 ，那么就线程等待
        return ((r = result) == null && !isCancel()) ? timedGet(nanos) : r;
    }


    public boolean isCancel() {
        return UNSAFE.getInt(this, STATE) <= CANCEL;
    }

    public boolean setCancel() {
        return UNSAFE.compareAndSwapInt(this, STATE, START, CANCEL);
    }

    public boolean isComplete() {
        return UNSAFE.getInt(this, STATE) >= COMPLETE;
    }


    /**
     * Returns raw result after waiting, or null if interrupted, or
     * throws TimeoutException on timeout.
     */
    private T timedGet(long nanos) throws TimeoutException {
        if (Thread.interrupted()) return null;

        if (nanos <= 0L) {
            throw new TimeoutException();
        }
        long d = System.nanoTime() + nanos;

        Signaller q = new Signaller(true, nanos, d == 0L ? 1L : d);

        Object r;

        while ((r = result) == null && !isCancel()) {

            // 判断中断标准是否小于0 或者 等待时间 小于等于0

            if ((q.interruptControl < 0 || q.nanos <= 0L) && compareAndSetState(START, CANCEL)) {
                // 证明 线程需要中断 或者 等待时间已经过了，直接返回null
                return null;
            } else if (result == null && !isCancel()) {
                try {
                    do {
                        // 当前线程阻塞等待
                    } while ((result == null && !isCancel()) && q.isReleasable() && q.block());
                } catch (InterruptedException ie) {
                    // 线程中断异常
                    q.interruptControl = -1;

                }
            }
        }

        if (q.interruptControl < 0) {
            r = null;
        }

        return (T) r;
    }

    public boolean complete(T value) {
        boolean triggered = completeValue(value);
        // 唤醒线程
        postComplete();
        return triggered;
    }

    private final boolean completeValue(T t) {
        return compareAndSetObject(null, (t == null) ? null : t) && compareAndSetState(START, COMPLETE);
    }

    protected final boolean compareAndSetState(int expect, int update) {
        return UNSAFE.compareAndSwapInt(this, STATE, expect, update);
    }

    protected final boolean compareAndSetObject(Object expect, Object update) {
        return UNSAFE.compareAndSwapObject(this, RESULT, expect, update);
    }
    final void postComplete() {

        do {

        } while (isComplete() && !tryFire());
    }


    boolean tryFire() {
        Thread w;
        if ((w = waitThread) != null) {
            waitThread = null;
            // 唤醒 w 线程
            LockSupport.unpark(w);
        }
        return true;
    }
    @SuppressWarnings("serial")
    static final class Signaller implements ForkJoinPool.ManagedBlocker {
        // 等待时间
        long nanos;                    // wait time if timed
        // 等待结束时间，纳秒级别的
        final long deadline;           // non-zero if timed
        // 中断控制标志
        volatile int interruptControl; // > 0: interruptible, < 0: interrupted


        Signaller(boolean interruptible, long nanos, long deadline) {

            this.interruptControl = interruptible ? 1 : 0;
            this.nanos = nanos;
            this.deadline = deadline;
        }

        public boolean isReleasable() {


            // 判断线程是否被要求中断
            if (Thread.interrupted()) {
                int i = interruptControl;
                interruptControl = -1;
                if (i > 0) return false;
            }
            // 等待结束时间 - 当前系统时间 =剩余等待时间
            if (deadline != 0L && (nanos <= 0L || (nanos = deadline - System.nanoTime()) <= 0L)) {

                return false;
            }
            return true;
        }

        public boolean block() throws InterruptedException{
            // 判断是否不满足阻塞条件
            if (!isReleasable()) return false;
            else if (deadline == 0L) LockSupport.park(this);
            else if (nanos > 0L)
                // 线程阻塞等待
                LockSupport.parkNanos(this, nanos);
            return isReleasable();
        }
    }
}
